﻿namespace BomberJoe
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Threading;
    using System.Windows.Forms;
    using BomberGame;

    /// <summary>
    /// The main menu of the BomberJoe game.
    /// </summary>
    public partial class BomberJoe : Form
    {
        private readonly HashSet<Score> _players;

        /// <summary>
        /// Initializes a new instance of the BomberJoe class.
        /// </summary>
        public BomberJoe()
        {
            InitializeComponent();
            startButton.Enabled = false;
            this._players = new HashSet<Score>();
            ReadScores();
            newPlayerName.Text = "- New Player -";
            newPlayerName.MaxLength = 16;
            newPlayer.Enabled = false;
            label6.Text = string.Empty;
            label7.Text = string.Empty;
            label8.Text = string.Empty;

            UpdateSources();
            this.TopThree();
        }

        /// <summary>
        /// What happens when the StartButton is clicked.
        /// </summary>
        /// <param name="sender">sender object</param>
        /// <param name="e">e EventArgs</param>
        private void StartButtonClick(object sender, EventArgs e)
        {
            Profile player1 = new Profile(1, (Score)player1ComboBox.SelectedItem);
            Profile player2 = new Profile(2, (Score)player2ComboBox.SelectedItem);

            Visible = false;
            Thread thread = new Thread(() =>
                { 
                    Game1 game = new Game1(player1, player2);
                    game.Run();
                });
            thread.Start();
            thread.Join();
            UpdateSources();
            WriteScores();
            this.TopThree();
            Visible = true;
            Activate();
        }

        /// <summary>
        /// What happens when the NewPlayer button is clicked.
        /// </summary>
        /// <param name="sender">sender object</param>
        /// <param name="e">e EventArgs</param>
        private void NewPlayerClick(object sender, EventArgs e)
        {
            this._players.Add(new Score(newPlayerName.Text, 0, 0));
            UpdateSources();
            newPlayerName.Text = "- New Player -";
            newPlayer.Enabled = false;
        }

        /// <summary>
        /// What happens when the a new item is selected in Player2ComboBox.
        /// </summary>
        /// <param name="sender">sender object</param>
        /// <param name="e">e EventArgs</param>
        private void Player2ComboBoxSelectedIndexChanged(object sender, EventArgs e)
        {
            this.startButton.Enabled = this.player1ComboBox.Text != this.player2ComboBox.Text;
            Score s = (Score)player2ComboBox.SelectedItem;
            player2score.Text = s.GetPoints().ToString();
        }

        /// <summary>
        /// What happens when the a new item is selected in Player1ComboBox.
        /// </summary>
        /// <param name="sender">sender object</param>
        /// <param name="e">e EventArgs</param>
        private void Player1ComboBoxSelectedIndexChanged(object sender, EventArgs e)
        {
            this.startButton.Enabled = this.player1ComboBox.Text != this.player2ComboBox.Text;
            Score s = (Score)player1ComboBox.SelectedItem;
            player1score.Text = s.GetPoints().ToString();
        }

        /// <summary>
        /// What happens when the text in NewPlayerName is changed.
        /// </summary>
        /// <param name="sender">sender object</param>
        /// <param name="e">e EventArgs</param>
        private void NewPlayerNameTextChanged(object sender, EventArgs e)
        {
            if (newPlayerName.Text.Length > 0 && !newPlayerName.Text.StartsWith("-"))
            {
                newPlayer.Enabled = true;
            }
            else
            {
                newPlayer.Enabled = false;
            }
        }

        /// <summary>
        /// Update the player combo boxes.
        /// </summary>
        private void UpdateSources()
        {
            List<Score> playerNames1 = new List<Score>();
            List<Score> playerNames2 = new List<Score>();     
            foreach (Score s in this._players)
            {
                playerNames1.Add(s);
                playerNames2.Add(s);
            }

            player1ComboBox.DataSource = playerNames1;
            player2ComboBox.DataSource = playerNames2;
        }

        /// <summary>
        /// Write and save highscore on the harddrive.
        /// </summary>
        private void WriteScores()
        {
            StreamWriter writer = new StreamWriter("HighScore.joe");
            foreach (Score s in this._players)
            {
                writer.WriteLine(s.Name);
                writer.WriteLine(s.Kills);
                writer.WriteLine(s.Deaths);
            }

            writer.Close();
        }

        /// <summary>
        /// Read the scores from the saved highscores.
        /// </summary>
        private void ReadScores()
        {
            try
            {
                var reader = new StreamReader("HighScore.joe");
                while (!reader.EndOfStream)
                {
                    var name = reader.ReadLine();
                    var kills = int.Parse(reader.ReadLine());
                    var deaths = uint.Parse(reader.ReadLine());
                    this._players.Add(new Score(name, kills, deaths));
                }

                reader.Close();
            }
            catch (Exception)
            {
                WriteScores();
            }
        }

        /// <summary>
        /// Display the Top three highscores on the display.
        /// </summary>
        private void TopThree()
        {
            List<Score> sorted = this._players.ToList();
            sorted.Sort();
            int temp = sorted.Count;
            Console.WriteLine(temp);
            if (temp > 0)
            {
                Score numberOne = sorted[0];
                this.label6.Text = numberOne.Name + " " + numberOne.GetPoints();
            }

            if (temp > 1)
            {
                Score numberTwo = sorted[1];
                this.label7.Text = numberTwo.Name + " " + numberTwo.GetPoints();
            }

            if (temp > 2)
            {
                Score numberThree = sorted[2];
                this.label8.Text = numberThree.Name + " " + numberThree.GetPoints();
            }
        }
    }
}
